package cn.merchant.web;


import cn.itcast.pojo.*;
import cn.merchant.service.impl.MerchantPayServiceImpl;
import cn.itcast.util.OutputStringController;
import cn.merchant.service.impl.merchantServiceImpl;
import cn.wx.MerchantMyConfig;
import cn.wx.MyConfig;
import cn.wx.WXPay;
import cn.wx.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: 欧阳辉
 * @Description:
 * @Date: Created in 10:40 2020/4/28
 * @Modified By:
 */

@Slf4j
@RestController
@RequestMapping(value="/wxshop/merchant",produces="text/html;charset=UTF-8")
public class MerchantWxpay {

    @Autowired
    private StringRedisTemplate template;



    @Resource
    merchantServiceImpl merchantService;

    @Resource
    MerchantPayServiceImpl payService;
    @Resource
    OutputStringController osc;





    /**
     *
     * @Description:
     * 微信统一下单接口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
    public String doUnifiedOrder(@RequestBody Map<String,String> map) {
        //返回结果
        String results="";
        Map resultMap=new HashMap();
        String openid = map.get("openId");
        String name = map.get("name");
        int total_fee = Integer.parseInt(map.get("totalFee"));

        log.debug(openid);
        MerchantMyConfig config = null;
        WXPay wxpay =null;
        try {
            config = new MerchantMyConfig();
            wxpay= new WXPay(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        //生成的随机字符串
        String nonce_str = WXPayUtil.generateNonceStr();
        //获取客户端的ip地址
        //获取本机的ip地址
        InetAddress addr = null;
        try {
            addr = InetAddress.getLocalHost();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String spbill_create_ip = addr.getHostAddress();
        //支付金额，需要转成字符串类型，否则后面的签名会失败
        //int  total_fee=1;
        //商品描述
        String body = "环保金充值";
        //商户订单号
        //String out_trade_no = getOrderIdByTime();
        String out_trade_no= WXPayUtil.generateNonceStr();
        //统一下单接口参数
        HashMap<String, String> data = new HashMap<String, String>();
        data.put("appid", "wx578244d5b6022c06");
        data.put("mch_id", "1550181801");
        data.put("nonce_str", nonce_str);
        data.put("body", body);
        data.put("out_trade_no",out_trade_no);
        data.put("total_fee", String.valueOf(total_fee));
        data.put("spbill_create_ip", spbill_create_ip);
        data.put("notify_url", "https://www.dhnep.cn:443/wxshop/merchant/notify");
        data.put("trade_type","JSAPI");
        data.put("openid", openid);
        try {
            Map<String, String> rMap = wxpay.unifiedOrder(data);
            System.out.println("统一下单接口返回: " + rMap);

            //生成业务充值记录订单
            recharge recharge = new recharge();
            recharge.setOpenId(openid);
            recharge.setName(name);
            recharge.setRechargeTime(new Date());
            recharge.setRechargeSum(Double.valueOf(total_fee)/100);
            recharge.setRechargeNumber(out_trade_no);
            recharge.setPayNumber(rMap.get("prepay_id"));
            recharge.setPayType("微信支付");
            recharge.setPayState("未支付");
            recharge.setBillState("未入账");

            merchantService.addRecharge(recharge);




            String return_code = (String) rMap.get("return_code");
            String result_code = (String) rMap.get("result_code");
            String nonceStr = WXPayUtil.generateNonceStr();
            resultMap.put("nonceStr", nonceStr);
            Long timeStamp = System.currentTimeMillis() / 1000;
            if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                String prepayid = rMap.get("prepay_id");
                resultMap.put("package", "prepay_id="+prepayid);
                resultMap.put("signType", "MD5");
                //这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
                resultMap.put("timeStamp", timeStamp + "");
                //再次签名，这个签名用于小程序端调用wx.requesetPayment方法
                resultMap.put("appId","wx578244d5b6022c06");
                log.debug(resultMap.toString());
                String sign = WXPayUtil.generateSignature(resultMap, "0B2DC615EA4F78BC4B216AEA1A6DA63B");
                resultMap.put("paySign", sign);
                log.debug("生成的签名paySign : "+ sign);
                results = osc.resultSuccess("yes",resultMap);
                return results;
            }else{
                return  results;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return  results;
        }
    }


    /**
     *微信支付回调
     */
    @RequestMapping("notify")
    public String notify(HttpServletRequest request) {
        log.info("================================================开始处理微信小程序发送的异步通知");

        //1 获取微信支付异步回调结果
        String xmlResult = WXPayUtil.getPostStr(request);

        Map<String, String> resultMap = null;
        try {
            //将结果转成map
            resultMap = WXPayUtil.xmlToMap(xmlResult);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        //订单号
        String orderNo = resultMap.get("out_trade_no");
        log.info("订单号：------------------"+orderNo+"结束----------");
        String result_code = resultMap.get("result_code");
        //回调返回的加密签名 保存下来 下面会进行对比
        String sign = resultMap.get("sign");
        //去掉sign和利用微信回调回来的信息重新加密
        resultMap.remove("sign");
        String sign1="";
        try {
            //重新加密 获取加密的签名
            sign1=WXPayUtil.generateSignature(resultMap, "0B2DC615EA4F78BC4B216AEA1A6DA63B"); //签名
        }catch (Exception e){

        }


        String resultCode;
        String resultMsg;
        //对比微信回调的加密与重新加密是否一致  一致即为通过 不一致说明呗改动过 加密不通过
        log.info("==============================================开始对比加密++++++++++++++++++++++++++++++++++++++");
        if (sign.equals(sign1)) { //验签通过
            log.info("==============================================验签通过++++++++++++++++++++++++++++++++++++++");
            log.info(result_code);
            if (result_code.equals("SUCCESS")) {//业务结果为SUCCESS
                /**
                 * 这里写你要处理的逻辑
                 */
                //修改订单状态,增加账户金额
                recharge recharge = new recharge();
                recharge.setPayState("已支付");
                recharge.setBillState("已入账");
                recharge.setBillTime(new Date());
                recharge.setRechargeNumber(orderNo);

                boolean isupdate = merchantService.updateRecharge(recharge);
                resultCode = "SUCCESS";
                resultMsg = "成功";
            } else { // 业务结果为FALL
                resultCode = "FAIL";
                resultMsg = "业务结果为FAIL";
            }

        } else {
            resultCode = "FAIL";
            resultMsg = "验签未通过";
        }

        Map<String, String> returnMap = new HashMap<>();
        returnMap.put("return_code", resultCode);
        returnMap.put("return_msg", resultMsg);
        try {
            String s = WXPayUtil.mapToXml(returnMap);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }




    /**
     *
     * @Description:
     * 骑手提现入口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/cash", method = RequestMethod.POST)
    public String cash(HttpServletRequest request,@RequestBody Map<String,String> map) {
        //返回结果
        String results = "";
        Map resultMap = new HashMap();
        String openid = map.get("openId");
        String amount = map.get("amount");
        log.debug("商户提现开始");

        //try {
        merchant merchant = payService.queryByOpenId(openid);
        if (null == merchant) {
            results = osc.failure("no");
            return results;
        }
        //校验
        account account = payService.queryAccountByOpenId(openid);
        if (null != account) {
            if (account.getAccountMoneyBalance().compareTo(Double.valueOf(amount)) == -1) {//余额小于提现金额
                results = osc.failure("余额不足");
                return results;
            }
        } else {
            results = osc.failure("该账户不存在");
            return results;
        }


//
        //商户订单号
        String out_trade_no = getOrderIdByTime()+"UID"+merchant.getMerchantId();


        //创建提现记录
        withdraw withdraw = new withdraw();
        withdraw.setOpenId(openid);
        withdraw.setNumber(out_trade_no);
        withdraw.setName(merchant.getNickName());
        withdraw.setPhone(merchant.getMerchantPhone());
        withdraw.setApplyTime(new Date());
        withdraw.setUserType("2");
        withdraw.setType("微信提现");
        withdraw.setNum(Double.valueOf(amount));
        withdraw.setState("已申请");
        withdraw.setTransfer(new Date());

        withdraw withdraws = payService.createWithDraw(withdraw);
        if(withdraws!=null){
            log.debug("创建提现记录成功");
            results = osc.success("创建提现记录成功");
        }else {
            log.debug("创建提现记录失败");
            results = osc.failure("创建提现记录失败");
        }
        return results;
    }



    /**
     *
     * @Description:
     * 这里不是用户提现入口
     * @auther: 欧阳辉
     * @date: 8:12 2020/3/17
     * @param: [request]
     * @return: java.lang.String
     *
     */
    @RequestMapping(value = "/cashUser", method = RequestMethod.POST)
    public String cashUser(HttpServletRequest request,@RequestBody Map<String,String> map) {
        //返回结果
        String results = "";
        Map resultMap = new HashMap();
        String openid = map.get("openId");
        String amount = map.get("amount");
        log.debug("用户提现开始");

        user user = payService.queryByUserOpenId(openid);
        if (null == user) {
            results = osc.failure("no");
            return results;
        }
        //校验
        account account = payService.queryAccountByOpenIdByUser(openid);
        if (null != account) {
            if (account.getAccountMoneyBalance().compareTo(Double.valueOf(amount)) == -1) {//余额小于提现金额
                results = osc.failure("余额不足");
                return results;
            }
        } else {
            results = osc.failure("该账户不存在");
            return results;
        }

        //商户订单号
        String out_trade_no = getOrderIdByTime()+"UID"+user.getUserWxid();

        //创建提现记录
        withdraw withdraw = new withdraw();
        withdraw.setOpenId(openid);
        withdraw.setNumber(out_trade_no);
        withdraw.setName(user.getNickName());
        withdraw.setPhone(user.getUserPhone());
        withdraw.setApplyTime(new Date());
        withdraw.setUserType("1");
        withdraw.setType("微信提现");
        withdraw.setNum(Double.valueOf(amount));
        withdraw.setState("已申请");
        withdraw.setTransfer(new Date());

        withdraw withdraws = payService.createWithDraw(withdraw);
        if(withdraws!=null){
            log.debug("创建提现记录成功");
            return osc.success("创建提现记录成功");
        }else {
            log.debug("创建提现记录失败");
            return osc.failure("创建提现记录失败");
        }




    }



    /**
     *
     * @Description:
     * 随机生成订单号
     * @auther: 欧阳辉
     * @date: 8:23 2020/3/17
     * @param: []
     * @return: java.lang.String
     *
     */
    public String getOrderIdByTime() {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
        String newDate=sdf.format(new Date());
        String result="";
        Random random=new Random();
        for(int i=0;i<3;i++){
            result+=random.nextInt(10);
        }
        return newDate+result;
    }





}